﻿using System;
using System.Text;

using SocketBuffer;

using PipeClient.Enum;
using PipeClient.Model;

using RpcHelper;

namespace PipeClient
{
        internal class PipeTools
        {
                private const byte _PageVer = 253;
                public const int HeadLen = 9;
                public static void ReadPage(object data)
                {
                        Model.GetDataPage arg = (Model.GetDataPage)data;
                        arg.Allot.InitInfo(arg);
                        string type = arg.Type;
                        object resData = arg.Allot.Action(ref type);
                        if (resData != null && (PageType.单向 & arg.PageType) != PageType.单向)
                        {
                                Page page = Page.GetReplyPage(arg, type, resData);
                                if (!arg.Client.SendPage(page, out string error))
                                {
                                        new LogInfo(error, LogGrade.ERROR, "Socket_Client")
                                        {
                                                LogTitle = "回复事件包错误!",
                                                LogContent = page.ToJson()
                                        }.Save();
                                }
                        }
                }

                /// <summary>
                /// 组建数据包
                /// </summary>
                /// <param name="data"></param>
                /// <param name="num"></param>
                /// <param name="objPage"></param>
                internal static bool SplitPage(byte[] data, int len, ref Model.DataPageInfo objPage, Client.PipeClient client)
                {
                        int index = 0;
                        return PipeTools.SplitPage(data, len, ref index, ref objPage, client);
                }
                internal static bool SplitPage(byte[] data, int len, ref int index, ref Model.DataPageInfo objPage, Client.PipeClient client)
                {
                        if (objPage == null)
                        {
                                if (data[index] != _PageVer)
                                {
                                        return false;
                                }
                                objPage = new Model.DataPageInfo();
                        }
                        if (objPage.LoadData(data, len, ref index))
                        {
                                client.ReceiveComplate();
                                if (index < len)
                                {
                                        return PipeTools.SplitPage(data, len, ref index, ref objPage, client);
                                }
                                return true;
                        }
                        return objPage.LoadProgress != PageLoadProgress.包校验错误;
                }

                /// <summary>
                /// 获取发送的字节流
                /// </summary>
                /// <param name="pageInfo"></param>
                /// <returns></returns>
                internal static ISocketBuffer GetSendBuffer(DataPage page)
                {
                        ISocketBuffer buffer = BufferCollect.ApplySendBuffer(page.GetPageSize(), page.DataId);
                        _InitPageHead(buffer, page);
                        return buffer;
                }
                private static int _InitHeadBody(ISocketBuffer buffer, DataPage page)
                {
                        int index = 9;
                        if (page.DataLen <= short.MaxValue)
                        {
                                index += buffer.WriteShort((short)page.DataLen, index);
                        }
                        else
                        {
                                index += buffer.WriteInt(page.DataLen, index);
                        }
                        index += buffer.WriteByte(Tools.CSByByte(buffer.Stream, index), index);
                        index += buffer.WriteChar(page.Type, index);
                        return index;
                }

                /// <summary>
                /// 获取包头信息
                /// </summary>
                /// <param name="pageId"></param>
                /// <param name="page"></param>
                /// <returns></returns>
                private static void _InitPageHead(ISocketBuffer buffer, DataPage page)
                {
                        buffer.WriteByte(_PageVer, 0);
                        buffer.WriteByte((byte)page.PageType, 1);
                        buffer.WriteByte((byte)page.DataType, 2);
                        buffer.WriteByte(page.HeadType, 3);
                        buffer.WriteInt(page.DataId, 4);
                        buffer.WriteByte(page.TypeLen, 8);
                        if (page.DataLen != 0)
                        {
                                int len = _InitHeadBody(buffer, page);
                                buffer.Write(page.Content, len);
                        }
                        else
                        {
                                buffer.WriteByte(Tools.CSByByte(buffer.Stream, 9), 9);
                                buffer.WriteChar(page.Type, 10);
                        }
                }
        }
}
